package bb.lanxing.mvp.model;

import static bb.lanxing.activity.routebook.RouteBookInfoActivity.REQUEST_TYPE_ROUTE_BOOK_INFO;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.alibaba.fastjson.JSON;

import bb.lanxing.common.cache.CacheEntity;
import bb.lanxing.common.cache.CacheManager;
import bb.lanxing.common.cache.CacheType;
import bb.lanxing.model.database.PostQueue;
import bb.lanxing.model.database.RouteBook;
import bb.lanxing.model.json.RouteBookComment;
import bb.lanxing.mvp.model.i.IRouteInfoModel;
import bb.lanxing.network.MyHttpClient;
import bb.lanxing.network.NetSubscribe;
import bb.lanxing.util.JsonUtil;
import bb.lanxing.util.RouteBookUtil;
import rx.Observable;
import rx.schedulers.Schedulers;

public class RouteInfoModelImpl implements IRouteInfoModel {
    @Override
    public Observable<List<RouteBookComment>> readCommentsFromCache(final RouteBook routeBook) {
        return Observable.just(routeBook.getServerId()).subscribeOn(Schedulers.io()).flatMap(aLong -> {
            ArrayList<RouteBookComment> arrayList = new ArrayList<>();
            List<CacheEntity> cache = CacheManager.getInstance().getCache(CacheType.LushuComment, routeBook.getServerId());
            for (int i = 0; cache != null && i < cache.size(); i++) {
                try {
                    arrayList.addAll(RouteInfoModelImpl.this.parseComments(cache.get(i).getContent(), routeBook));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return Observable.just(arrayList);
        });
    }

    @Override
    public Observable<List<RouteBookComment>> requestCommentFromServers(RouteBook routeBook) {
        return requestCommentFromServers(routeBook, 0);
    }

    @Override
    public Observable<List<RouteBookComment>> requestCommentFromServers(final RouteBook routeBook, int startOffset) {
        return Observable
                .create(new NetSubscribe(MyHttpClient.requestLushuComment(routeBook.getServerId(), startOffset, 20)))
                .subscribeOn(Schedulers.io()).flatMap(s -> {
                    try {
                        JSONObject jsonObject = new JSONObject(s);
                        if (200 == jsonObject.getInt("code")) {
                            JSONArray jsonArray = new JSONArray(jsonObject.getString("data"));
                            return Observable.just(RouteInfoModelImpl.this.parseComments(jsonArray, routeBook));
                        } else {
                            return null;
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                        return null;
                    }
                });
    }

    @Override
    public Observable<RouteBook> queryLushu(RouteBook routeBook) {
        if (routeBook == null) {
            return Observable.just(null);
        }
        return Observable.just(routeBook.getServerId()).subscribeOn(Schedulers.io()).map(RouteBook::getByServerId);
    }

    @Override
    public Observable<RouteBook> requestRouteInfo(RouteBook routeBook) {
        return Observable
                .create(new NetSubscribe(MyHttpClient.requestLushuInfo(routeBook.getServerId(), REQUEST_TYPE_ROUTE_BOOK_INFO)))
                .subscribeOn(Schedulers.io()).flatMap(str -> {
                    try {
                        JSONObject jsonObject = new JSONObject(str);
                        JSONObject jsonObjectData = jsonObject.getJSONObject("data");
                        return Observable.just(RouteBook.parseLushuByServer(jsonObjectData, true));
                    } catch (JSONException e) {
                        e.printStackTrace();
                        return null;
                    }
                });
    }

    @Override
    public Observable<Boolean> deleteRouteComment(long routeServersId, long commentId) {
        return Observable.create(new NetSubscribe(MyHttpClient.deleteCommentForLushu(routeServersId, commentId)))
                .subscribeOn(Schedulers.io()).flatMap(s -> {
                    try {
                        if (new JSONObject(s).getInt("code") == 200) {
                            return Observable.just(true);
                        }
                        return Observable.just(false);
                    } catch (JSONException e) {
                        e.printStackTrace();
                        return null;
                    }
                });
    }

    @Override
    public Observable<Boolean> routeCollectionControl(long routeServersId, int type) {
        return Observable.create(new NetSubscribe(MyHttpClient.lushuCollectionControl(routeServersId, type)))
                .subscribeOn(Schedulers.io()).flatMap(str -> Observable.just(true));
    }

    @Override
    public Observable<RouteBook> downloadRoute(final RouteBook routeBook) {
        final NetSubscribe netSubscribe = new NetSubscribe(
                MyHttpClient.downloadRouteBook(routeBook.getServerType(), routeBook.getServerId()));
        return Observable.create(netSubscribe).subscribeOn(Schedulers.io()).flatMap(s -> {
            try {
                JSONObject jsonObject = new JSONObject(s);
                JSONObject jsonObjectData = jsonObject.getJSONObject("data");
                RouteBookUtil.parseDirectionNew(jsonObjectData.toString(), null, routeBook, routeBook.getSourceType());
                return Observable.just(routeBook);
            } catch (JSONException e) {
                e.printStackTrace();
                return null;
            }
        });
    }

    @Override
    public Observable<String> downloadRoute(long serverId) {
        final NetSubscribe netSubscribe = new NetSubscribe(MyHttpClient.downloadRouteBookFile(serverId));
        return Observable.create(netSubscribe).subscribeOn(Schedulers.io());
    }

    public List<RouteBookComment> parseComments(String string, RouteBook routeBook) throws JSONException {
        JSONObject jSONObject = new JSONObject(string);
        routeBook.setCommentCount(JsonUtil.getIntegerValue("comment_num", jSONObject));
        routeBook.setDownloadCount(JsonUtil.getIntegerValue("download_time", jSONObject));
        JSONArray arrayValue = JsonUtil.getArrayValue("comment", jSONObject);
        ArrayList<RouteBookComment> arrayList = new ArrayList<>();
        if (arrayValue != null && arrayValue.length() > 0) {
            for (int i = 0; i < arrayValue.length(); i++) {
                arrayList.add(new RouteBookComment(arrayValue.getJSONObject(i)));
            }
        }
        List<PostQueue> typedPostQueueSync =
                new PostQueueModelImpl().getTypedPostQueueSync(PostQueue.TYPE_LUSHU_COMMENT, routeBook.getServerId(), true);
        if (typedPostQueueSync != null && !typedPostQueueSync.isEmpty()) {
            for (int i2 = 0; i2 < typedPostQueueSync.size(); i2++) {
                PostQueue postQueue = typedPostQueueSync.get(i2);
                RouteBookComment routeBookComment = JSON.parseObject(postQueue.getContent(), RouteBookComment.class);
                routeBookComment.setTime(postQueue.getState() == 2 ? -2L : -1L);
                arrayList.add(0, routeBookComment);
            }
        }
        return arrayList;
    }

    public List<RouteBookComment> parseComments(JSONArray jsonArray, RouteBook routeBook) throws JSONException {
        int commentNum = jsonArray.length();
        routeBook.setCommentCount(commentNum);
        ArrayList<RouteBookComment> arrayList = new ArrayList<>();
        if (jsonArray.length() > 0) {
            for (int i = 0; i < jsonArray.length(); i++) {
                arrayList.add(new RouteBookComment(jsonArray.getJSONObject(i)));
            }
        }
        List<PostQueue> typedPostQueueSync =
                new PostQueueModelImpl().getTypedPostQueueSync(PostQueue.TYPE_LUSHU_COMMENT, routeBook.getServerId(), true);
        if (typedPostQueueSync != null && !typedPostQueueSync.isEmpty()) {
            for (int i2 = 0; i2 < typedPostQueueSync.size(); i2++) {
                PostQueue postQueue = typedPostQueueSync.get(i2);
                RouteBookComment routeBookComment = JSON.parseObject(postQueue.getContent(), RouteBookComment.class);
                routeBookComment.setTime(postQueue.getState() == 2 ? -2L : -1L);
                arrayList.add(0, routeBookComment);
            }
        }
        return arrayList;
    }
}
